/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package cy.mybatis.genui;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author cangyan
 */
public class GeneratorConfiguration {
    private String driverPath;
    private String driverClass;
    private String connectionURL;
    private String distSrcDir;
    private String modelPack;
    private String mapPack;
    private String daoPack;
    private String userName;
    private String password;
    private String enableCountByExample = "false";
    private String enableUpdateByExample = "false";
    private String enableDeleteByExample = "false";
    private String enableSelectByExample = "false";
    private String selectByExampleQueryId = "false";
    private List<String> tableList;
    public GeneratorConfiguration(){
        tableList = new ArrayList<String>();
    }
    private String getHead(){
        return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
    }

    public String getDriverClass() {
        return driverClass;
    }

    public void setDriverClass(String driverClass) {
        this.driverClass = driverClass;
    }

    public String getConnectionURL() {
        return connectionURL;
    }

    public void setConnectionURL(String connectionURL) {
        this.connectionURL = connectionURL;
    }

    public String getDistSrcDir() {
        return distSrcDir;
    }

    public void setDistSrcDir(String distSrcDir) {
        this.distSrcDir = distSrcDir;
    }

    public String getModelPack() {
        return modelPack;
    }

    public void setModelPack(String modelPack) {
        this.modelPack = modelPack;
    }

    public String getMapPack() {
        return mapPack;
    }

    public void setMapPack(String mapPack) {
        this.mapPack = mapPack;
    }

    public String getDaoPack() {
        return daoPack;
    }

    public void setDaoPack(String daoPack) {
        this.daoPack = daoPack;
    }

    public String getEnableCountByExample() {
        return enableCountByExample;
    }

    public void setEnableCountByExample(String enableCountByExample) {
        this.enableCountByExample = enableCountByExample;
    }

    public String getEnableUpdateByExample() {
        return enableUpdateByExample;
    }

    public void setEnableUpdateByExample(String enableUpdateByExample) {
        this.enableUpdateByExample = enableUpdateByExample;
    }

    public String getEnableDeleteByExample() {
        return enableDeleteByExample;
    }

    public void setEnableDeleteByExample(String enableDeleteByExample) {
        this.enableDeleteByExample = enableDeleteByExample;
    }

    public String getEnableSelectByExample() {
        return enableSelectByExample;
    }

    public void setEnableSelectByExample(String enableSelectByExample) {
        this.enableSelectByExample = enableSelectByExample;
    }

    public String getSelectByExampleQueryId() {
        return selectByExampleQueryId;
    }

    public void setSelectByExampleQueryId(String selectByExampleQueryId) {
        this.selectByExampleQueryId = selectByExampleQueryId;
    }

    public List<String> getTableList() {
        return tableList;
    }

    public void setTableList(List<String> tableList) {
        this.tableList = tableList;
    }

    public String getDriverPath() {
        return driverPath;
    }

    public void setDriverPath(String driverPath) {
        this.driverPath = driverPath;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    
    private String getDoctype(){
        StringBuilder doctype = new StringBuilder();
        doctype.append("<!DOCTYPE generatorConfiguration PUBLIC ");
        doctype.append("\"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN\" ");
        doctype.append("\"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd\">");
        return doctype.toString();
    }
    
    private String getClassPathEntry(String path){
        StringBuilder sb = new StringBuilder();
        sb.append("<classPathEntry location=\"");
        sb.append(path);
        sb.append("\" />");
        return sb.toString();
    }
    
    private String getCommentGenerator(String suppressAllComments,String suppressDate){
        StringBuilder sb = new StringBuilder();
        sb.append("<commentGenerator>");
        sb.append("<property name=\"suppressAllComments\" ");
        sb.append("value=\"").append(suppressAllComments).append("\" />");
        sb.append("<property name=\"suppressDate\" ");
        sb.append("value=\"").append(suppressDate).append("\" />");
        sb.append("</commentGenerator>");
        return sb.toString();
    }
    
    private String getJdbcConnection(String driverClass,String connectionURL,String user,String password){
        StringBuilder sb = new StringBuilder();
        sb.append("<jdbcConnection driverClass=\"");
        sb.append(driverClass);
        sb.append("\" connectionURL=\"");
        sb.append(connectionURL);
        sb.append("\"  userId=\"");
        sb.append(user);
        sb.append("\"  password=\"");
        sb.append(password);
        sb.append("\"> </jdbcConnection>");
        return sb.toString();
    }
    
    private String getJavaTypeResolver(){
        StringBuilder sb = new StringBuilder();
        sb.append("<javaTypeResolver >");
        sb.append("<property name=\"forceBigDecimals\" value=\"false\" />");
        sb.append("</javaTypeResolver>");
        return sb.toString();
    }
    private String getJavaModelGenerator(String pack,String path){
        StringBuilder sb = new StringBuilder();
        sb.append("<javaModelGenerator targetPackage=\"");
        sb.append(pack);
        sb.append("\" targetProject=\"");
        sb.append(path);
        sb.append("\">");
        sb.append("<property name=\"enableSubPackages\" value=\"true\" />");
        sb.append("<property name=\"trimStrings\" value=\"false\" />");
        sb.append("</javaModelGenerator>");
        return sb.toString();
    }
    private String getSqlMapGenerator(String pack,String path){
        StringBuilder sb = new StringBuilder();
        sb.append("<sqlMapGenerator targetPackage=\"");
        sb.append(pack);
        sb.append("\" targetProject=\"");
        sb.append(path);
        sb.append("\">");
        sb.append("<property name=\"enableSubPackages\" value=\"true\" />");
        sb.append("</sqlMapGenerator>");
        return sb.toString();
    }
    
    private String getJavaClientGenerator(String pack,String path){
        StringBuilder sb = new StringBuilder();
        sb.append("<javaClientGenerator type=\"XMLMAPPER\" targetPackage=\"");
        sb.append(pack);
        sb.append("\" targetProject=\"");
        sb.append(path);
        sb.append("\">");
        sb.append("<property name=\"enableSubPackages\" value=\"true\" />");
        sb.append("</javaClientGenerator>");
        return sb.toString();
    }
        private String getTable(String tableName, String domainObjectName,String enableCount,String enableUpdate,
                String enableDelete, String enableSelect,String enableQueryId){
        StringBuilder sb = new StringBuilder();
        sb.append("<table tableName=\"").append(tableName).append("\" ");
        sb.append("domainObjectName=\"").append(domainObjectName).append("\" ");
        sb.append("enableCountByExample=\"").append(enableCount).append("\" ");
        sb.append("enableUpdateByExample=\"").append(enableUpdate).append("\" ");
        sb.append("enableDeleteByExample=\"").append(enableDelete).append("\" ");
        sb.append("enableSelectByExample=\"").append(enableSelect).append("\" ");
        sb.append("selectByExampleQueryId=\"").append(enableQueryId).append("\" ");
        sb.append(" />  ");
        return sb.toString();
    }
    public InputStream parse(){
        StringBuilder sb = new StringBuilder();
        sb.append(getHead());
        sb.append(getDoctype());
        sb.append("<generatorConfiguration>");
        sb.append(getClassPathEntry(driverPath));
        sb.append("<context id=\"myTables\" targetRuntime=\"MyBatis3\">");
        sb.append(getCommentGenerator("true", "true"));
        sb.append(getJdbcConnection(driverClass, connectionURL, userName, password));
        sb.append(getJavaTypeResolver());
        sb.append(getJavaModelGenerator(modelPack, distSrcDir));
        sb.append(getSqlMapGenerator(mapPack, distSrcDir));
        sb.append(getJavaClientGenerator(daoPack, distSrcDir));
        for (String tableName : tableList) {
            sb.append(getTable(tableName, lineToCamel(tableName,true), enableCountByExample, enableUpdateByExample, enableDeleteByExample, enableSelectByExample, selectByExampleQueryId));
        }
        sb.append("</context>");
        sb.append("</generatorConfiguration>");
        System.out.println(sb.toString());
        try{
            InputStream is = new ByteArrayInputStream(sb.toString().getBytes());
            return is;
        }catch(Exception e){
            CyUtil.writeLog(this.getClass(), e);
        } 
        return null;
    }
    
    public static String lineToCamel(String str, boolean firstUpperCase) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        str = str.toLowerCase();
        int len = str.length();
        StringBuilder sb = new StringBuilder();
        boolean upperCase = firstUpperCase;
        for (int i = 0; i < len; i++) {
            char c = str.charAt(i);
            if (c == '_') {
                upperCase = true;
                continue;
            }
            if (upperCase) {
                sb.append(Character.toUpperCase(str.charAt(i)));
                upperCase = false;
            } else {
                sb.append(str.charAt(i));
            }
        }
        return sb.toString();
    }
}
